/*
 *   This File is Part of CuteOgre Game Engine
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *	Copyright 2010 Alexandre Pires ( c.alexandre.pires@gmail.com )
 *  Created on: 2010/08/22
 */


#ifndef THEORASTREAM_H_
#define THEORASTREAM_H_

#include "IOggStream.h"

#include <theora/theora.h>
#include <theora/theoradec.h>

#include <QSharedPointer>
#include <QMutex>

#include "OGRE/OgrePixelFormat.h"
#include "OGRE/OgreHardwarePixelBuffer.h"

class OggFile;

class TheoraStream: public IOggStream {

	friend class OggFile;

public:

	virtual ~TheoraStream();

	inline unsigned char getVersionMajor() const {
		return mInfo.version_major;
	}

	inline unsigned char getVersionMinor() const {
		return mInfo.version_minor;
	}

	inline unsigned char getVersionSubMinor() const {
		return mInfo.version_subminor;
	}

	inline ogg_uint32_t getFrameWidth() const {
		return mInfo.frame_width;
	}

	inline ogg_uint32_t getFrameHeight() const {
		return mInfo.frame_height;
	}

	inline ogg_uint32_t getPicWidth() const {
		return mInfo.pic_width;
	}

	inline ogg_uint32_t getPicHeight() const {
		return mInfo.pic_height;
	}

	inline ogg_uint32_t getPicX() const {
		return mInfo.pic_x;
	}

	inline ogg_uint32_t getPicY() const {
		return mInfo.pic_y;
	}

	inline ogg_uint32_t getFpsNumerator() const {
		return mInfo.fps_numerator;
	}

	inline ogg_uint32_t getFpsDenominator() const {
		return mInfo.fps_denominator;
	}

	inline ogg_uint32_t getAspectNumerator() const {
		return mInfo.aspect_numerator;
	}

	inline ogg_uint32_t getAspectDenominator() const {
		return mInfo.aspect_denominator;
	}

	inline th_colorspace getColorspace() const {
		return mInfo.colorspace;
	}

	inline th_pixel_fmt getPixelFmt() const {
		return mInfo.pixel_fmt;
	}

	inline int getTargetBitrate() const {
		return mInfo.target_bitrate;
	}

	inline int getQuality() const {
		return mInfo.quality;
	}

	inline float getLastFrameTime () {
		return ( mLastFrameTime );
	}

	QString streamInfo() const {
		return QString(
				"TheoraStream (%7) -> Version: %1.%2.%3, width: %4, height: %5, bitrate: %6").arg(
				getVersionMajor()).arg(getVersionMinor()).arg(getVersionSubMinor()).arg(
				getFrameWidth()).arg(getFrameHeight()).arg(getTargetBitrate()).arg(mSerial);
	}

	inline int getSerial() const {
		return mSerial;
	}

	inline StreamType getStreamType() const {
		return IOggStream::TYPE_VORBIS;
	}

	inline bool isActive() {
		return mActive;
	}

	inline void disable () {
		mActive = false;
	}

	bool read ( Ogre::PixelBox* rBuffer );

protected:

	TheoraStream(int rSerial = -1, OggFile* rFile = 0);

	void processHeaders ();

	inline void lockState() {
		mMutex.lock();
	}

	inline void unlockState() {
		mMutex.unlock();
	}

	inline ogg_stream_state* getState() {
		return &mState;
	}

	static bool checkHeaderSignature(ogg_packet* rPacket);
	static bool checkHeaderSignature(ogg_page* rPage);

private:
	bool handle_theora_header(ogg_packet* rPacket);

protected:
	/* OGG stream state*/
	int mSerial;
	ogg_stream_state mState;
	ogg_int64_t  mGranulepos;

	/* Theora info*/
	th_info mInfo;
	th_comment mComment;
	th_setup_info *mSetup;
	th_dec_ctx* mCtx;


	float mLastFrameTime;
	OggFile* mFile;
	QMutex mMutex;
	bool mHeaderDone,mActive;
};

typedef QSharedPointer<TheoraStream> TheoraStreamPtr;


#endif /* THEORASTREAM_H_ */
